﻿using System;
using System.Xml.Linq;

namespace Bing
{
    // TODO: Documentation Error: http://msdn.microsoft.com/en-us/library/dd877839.aspx, XML implementation point to an invalid page. It should be http://msdn.microsoft.com/en-us/library/dd877882.aspx
    /// <summary>
    /// This class maps to the returned record from a <see cref="InstantAnswerRequest"/> when flight information is requested
    /// </summary>
    public class FlightStatus
    {
        /// <summary>
        /// Gets or sets the 2-letter code for an airline.
        /// </summary>
        /// <value>2-letter code for an airline.</value>
        public string AirlineCode { get; set; }
        /// <summary>
        /// Gets or sets the name of the airline.
        /// </summary>
        /// <value>The name of the airline.</value>
        public string AirlineName { get; set; }
        /// <summary>
        /// Gets or sets the number of a flight.
        /// </summary>
        /// <value>Number of a flight.</value>
        public string FlightNumber { get; set; }
        /// <summary>
        /// Gets or sets the full identifier of a flight.
        /// </summary>
        /// <value>TFull identifier of a flight.</value>
        public string FlightName { get; set; }
        /// <summary>
        /// Gets or sets the unique identifier for a specific instance of a flight.
        /// </summary>
        /// <value>Unique identifier for a specific instance of a flight .</value>
        public UInt32 FlightHistoryId { get; set; }
        /// <summary>
        /// Gets or sets the status of a flight.
        /// </summary>
        /// <value>Status of a flight.</value>
        public string StatusString { get; set; }
        /// <summary>
        /// Gets or sets the 2-digit code that indicates the status of a flight.
        /// </summary>
        /// <value>The 2-digit code that indicates the status of a flight.</value>
        public UInt32 StatusCode { get; set; }
        /// <summary>
        /// Gets or sets the progress of a flight with respect to schedule
        /// </summary>
        /// <value>Progress of a flight with respect to schedule.</value>
        public string OnTimeString { get; set; }
        /// <summary>
        /// Gets or sets the scheduled date and time of departure for a flight.
        /// </summary>
        /// <value>Scheduled date and time of departure for a flight.</value>
        public DateTime ScheduledDeparture { get; set; }
        /// <summary>
        /// Gets or sets the updated date and time of departure for a flight.
        /// </summary>
        /// <value>The updated date and time of departure for a flight.</value>
        public DateTime UpdatedDeparture { get; set; }
        /// <summary>
        /// Gets or sets the scheduled date and time of arrival for a flight.
        /// </summary>
        /// <value>The scheduled date and time of arrival for a flight.</value>
        public DateTime ScheduledArrival { get; set; }

        // TODO: Documentation Error: http://msdn.microsoft.com/en-us/library/dd250870.aspx 
        /// <summary>
        /// Gets or sets the updated date and time of arrival for a flight.
        /// </summary>
        /// <value>The updated date and time of arrival for a flight.</value>
        public DateTime UpdatedArrival { get; set; }
        /// <summary>
        /// Gets or sets the origin airport.
        /// </summary>
        /// <value>The origin airport.</value>
        public Airport OriginAirport { get; set; }
        /// <summary>
        /// Gets or sets the destination airport.
        /// </summary>
        /// <value>The destination airport.</value>
        public Airport DestinationAirport { get; set; }
        /// <summary>
        /// Gets or sets the departure gate.
        /// </summary>
        /// <value>The departure gate.</value>
        public string DepartureGate { get; set; }
        /// <summary>
        /// Gets or sets the departure terminal.
        /// </summary>
        /// <value>The departure terminal.</value>
        public string DepartureTerminal { get; set; }
        /// <summary>
        /// Gets or sets the arrival gate.
        /// </summary>
        /// <value>The arrival gate.</value>
        public string ArrivalGate { get; set; }
        /// <summary>
        /// Gets or sets the arrival terminal.
        /// </summary>
        /// <value>The arrival terminal.</value>
        public string ArrivalTerminal { get; set; }
        /// <summary>
        /// Gets or sets the previous segment of the flight.
        /// </summary>
        /// <value>The previous segment of the flight.</value>
        public FlightSegment PreviousSegment { get; set; }
        /// <summary>
        /// Gets or sets the next segment of the flight.
        /// </summary>
        /// <value>The next segment of the flight.</value>
        public FlightSegment NextSegment { get; set; }
        /// <summary>
        /// Gets or sets the number of minutes since this data was refreshed.
        /// </summary>
        /// <value>Number of minutes since this data was refreshed.</value>
        public int DataFreshness { get; set; }

        /// <summary>
        /// Parses the flight status.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns></returns>
        public static FlightStatus ParseFlightStatus(XElement element)
        {
            FlightStatus flightStatus = new FlightStatus();

            flightStatus.AirlineCode = ApiHelper.GetElementValueOrDefault<string>(element, "AirlineCode", ApiHelper.FlightStatusNs);
            flightStatus.AirlineName = ApiHelper.GetElementValueOrDefault<string>(element, "AirportName", ApiHelper.FlightStatusNs);
            flightStatus.FlightNumber = ApiHelper.GetElementValueOrDefault<string>(element, "FlightNumber", ApiHelper.FlightStatusNs);
            flightStatus.FlightName = ApiHelper.GetElementValueOrDefault<string>(element, "FlightName", ApiHelper.FlightStatusNs);
            flightStatus.FlightHistoryId = ApiHelper.GetElementValueOrDefault<UInt32>(element, "FlightHistoryId", ApiHelper.FlightStatusNs);
            flightStatus.StatusString = ApiHelper.GetElementValueOrDefault<string>(element, "StatusString", ApiHelper.FlightStatusNs);
            flightStatus.StatusCode = ApiHelper.GetElementValueOrDefault<UInt32>(element, "StatusCode", ApiHelper.FlightStatusNs);
            flightStatus.OnTimeString = ApiHelper.GetElementValueOrDefault<string>(element, "OnTimeString", ApiHelper.FlightStatusNs);
            flightStatus.ScheduledDeparture = ApiHelper.GetElementValueOrDefault<DateTime>(element, "ScheduledDeparture", ApiHelper.FlightStatusNs);
            flightStatus.UpdatedDeparture = ApiHelper.GetElementValueOrDefault<DateTime>(element, "UpdatedDeparture", ApiHelper.FlightStatusNs);
            flightStatus.ScheduledArrival = ApiHelper.GetElementValueOrDefault<DateTime>(element, "ScheduledArrival", ApiHelper.FlightStatusNs);
            flightStatus.UpdatedArrival = ApiHelper.GetElementValueOrDefault<DateTime>(element, "UpdatedArrival", ApiHelper.FlightStatusNs);
            flightStatus.DepartureGate = ApiHelper.GetElementValueOrDefault<string>(element, "DepartureGate", ApiHelper.FlightStatusNs);
            flightStatus.DepartureTerminal = ApiHelper.GetElementValueOrDefault<string>(element, "DepartureTerminal", ApiHelper.FlightStatusNs);
            flightStatus.ArrivalGate = ApiHelper.GetElementValueOrDefault<string>(element, "ArrivalGate", ApiHelper.FlightStatusNs);
            flightStatus.ArrivalTerminal = ApiHelper.GetElementValueOrDefault<string>(element, "ArrivalTerminal", ApiHelper.FlightStatusNs);
            flightStatus.DataFreshness = ApiHelper.GetElementValueOrDefault<int>(element, "DataFreshness", ApiHelper.FlightStatusNs);

            // Original Airport
            XElement originAirport = element.Element(XName.Get("OriginAirport", ApiHelper.FlightStatusNs));
            Airport airport = new Airport();
            airport.Code = ApiHelper.GetElementValueOrDefault<string>(originAirport, "Code", ApiHelper.FlightStatusNs);
            airport.Name = ApiHelper.GetElementValueOrDefault<string>(originAirport, "Name", ApiHelper.FlightStatusNs);
            airport.TimeZoneOffset = ApiHelper.GetElementValueOrDefault<int>(originAirport, "TimeZoneOffset", ApiHelper.FlightStatusNs);
            flightStatus.OriginAirport = airport;

            // Destination Airport
            XElement destinationAirport = element.Element(XName.Get("DestinationAirport", ApiHelper.FlightStatusNs));
            airport = new Airport();
            airport.Code = ApiHelper.GetElementValueOrDefault<string>(destinationAirport, "Code", ApiHelper.FlightStatusNs);
            airport.Name = ApiHelper.GetElementValueOrDefault<string>(destinationAirport, "Name", ApiHelper.FlightStatusNs);
            airport.TimeZoneOffset = ApiHelper.GetElementValueOrDefault<int>(destinationAirport, "TimeZoneOffset", ApiHelper.FlightStatusNs);
            flightStatus.DestinationAirport = airport;

            // Previous Segment
            XElement previousSegment = element.Element(XName.Get("PreviousSegment", ApiHelper.FlightStatusNs));
            FlightSegment flightSegment = new FlightSegment();
            flightSegment.FlightHistoryId = ApiHelper.GetElementValueOrDefault<UInt32>(previousSegment, "FlightHistoryId", ApiHelper.FlightStatusNs);
            flightSegment.OriginAirport = ApiHelper.GetElementValueOrDefault<string>(previousSegment, "OriginAirport", ApiHelper.FlightStatusNs);
            flightSegment.DestinationAirport = ApiHelper.GetElementValueOrDefault<string>(previousSegment, "DestinationAirport", ApiHelper.FlightStatusNs);
            flightStatus.PreviousSegment = flightSegment;

            // Next Segment
            XElement nextSegment = element.Element(XName.Get("NextSegment", ApiHelper.FlightStatusNs));
            flightSegment = new FlightSegment();
            flightSegment.FlightHistoryId = ApiHelper.GetElementValueOrDefault<UInt32>(nextSegment, "FlightHistoryId", ApiHelper.FlightStatusNs);
            flightSegment.OriginAirport = ApiHelper.GetElementValueOrDefault<string>(nextSegment, "OriginAirport", ApiHelper.FlightStatusNs);
            flightSegment.DestinationAirport = ApiHelper.GetElementValueOrDefault<string>(nextSegment, "DestinationAirport", ApiHelper.FlightStatusNs);
            flightStatus.NextSegment = flightSegment;

            return flightStatus;

        }
    }
}
